﻿using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.EventSystems;
using UnityEngine.UI;

/// <summary>
/// 长按按钮
/// </summary>
public class UGUILongButton : Button
{
    [Header("长按触发时间")]
    [SerializeField]
    public  float DelayTime = 0.2f;

    private float m_DelayTime = 0.2f;

    [Header("多次触发间隔")]
    [SerializeField]
    public float Interval;

    private float m_Interval = 0.1f;

    [Header("加速触发时间")]
    [SerializeField]
    public  float UpDelayTime = 0f;

    private float m_UpDelayTime = 0f;

    [Header("加速间隔")]
    [SerializeField]
    public  float UpInterval = 0.005f;

    private float m_UpInterval = 0.005f;

    // 最大速度
    private float m_LimitSpeed = 0.01f;

    private bool m_IsPress = false;
    private float m_NextEventTime = 0;
    private float m_UpSpeedStartTime = 0;

    private RectTransform rect = null;

    public Action<float> OnLongPress = null;

    public Action OnPointDown = null;
    public Action OnLongUp = null;

    private bool m_IsPause = false;

    private bool m_IsLongPress = false;

    public bool IsSpeedUp { get; private set; } = false;

    protected override void Awake()
    {
        base.Awake();
        rect = GetComponent<RectTransform>();

        m_Interval = Interval;
        m_DelayTime = DelayTime;
        m_UpDelayTime = UpDelayTime;
        m_UpInterval = UpInterval;

        m_IsLongPress = false;
    }

    private void Update()
    {
        if (m_IsPause)
        {
            m_NextEventTime += Time.deltaTime;
            return;
        }

        if (m_IsPress && Time.time > m_NextEventTime)
        {
            m_IsLongPress = true;
            OnLongPress?.Invoke(Time.time - m_NextEventTime);
            m_NextEventTime = Time.time + m_Interval;
            if (IsSpeedUp
                && Time.time > m_UpSpeedStartTime
                && m_Interval > m_LimitSpeed)
            {
                m_Interval -= m_UpInterval;
            }
        }
    }

    public void SetSpeedUp(bool isSpeedUp, float? speed = null, float? start = null)
    {
        IsSpeedUp = isSpeedUp;

        if (speed != null && speed is float)
            m_UpInterval = (float)speed;

        if (start != null && start is float)
            m_UpDelayTime = (float)start;
    }

    public void Pause()
    {
        m_IsPause = true;
        m_Interval = Interval;
    }

    public void Resume()
    {
        m_IsPause = false;
        m_Interval = Interval;
    }

    protected override void OnEnable()
    {
        base.OnEnable();
        Resume();
        m_IsPress = false;
        m_Interval = Interval;
    }

    protected override void OnDisable()
    {
        base.OnDisable();
        m_IsPress = false;
        m_Interval = Interval;
    }

    public override void OnPointerDown(PointerEventData eventData)
    {
        base.OnPointerDown(eventData);
        m_IsLongPress = false;
        m_IsPress = true;
        m_NextEventTime = Time.time + m_DelayTime;
        m_UpSpeedStartTime = Time.time + m_UpDelayTime;
        OnPointDown?.Invoke();
    }

    public void CheckIsPress()
    {
        if (!gameObject.activeSelf || !Input.GetButton("Fire1"))
        {
            m_IsPress = false;
            m_Interval = Interval;
            return;
        }

        //var camera = GameEntry.UI.InstanceRoot.GetComponent<Canvas>().worldCamera;
        //m_IsPress = RectTransformUtility.RectangleContainsScreenPoint(rect, Input.mousePosition, camera);
    }

    public override void OnPointerUp(PointerEventData eventData)
    {
        base.OnPointerUp(eventData);
        m_IsPress = false;
        m_Interval = Interval;
        OnLongUp?.Invoke();
    }

    public override void OnPointerClick(PointerEventData eventData)
    {
        if (m_IsLongPress)
            return;
        base.OnPointerClick(eventData);
    }
}
